package com.crm.redis.mapper;

import com.crm.redis.RedisTtlConfig;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
public class ListRMapper {

    /**
     * 根据key和hashkey获取一个值，并转化为castToClass所对应的类型
     *
     * @param redisTemplate
     * @param key
     * @param castToClass
     * @param <T>
     * @return
     */
    public static <T> List<T> getList(RedisTemplate<String, Object> redisTemplate, String key, Class<T> castToClass) {
        if (key == null) {
            return null;
        } else {
            try {
                List<T> resultList = null;
                List<Object> range = redisTemplate.opsForList().range(key, 0, -1);
                if (!range.isEmpty()) {
                	resultList = new LinkedList<>();
                    for (Object obj :
                            range) {
                        T targetObj = (T) obj;
                        resultList.add(targetObj);
                    }
                }
                return resultList;
            } catch (Exception e) {
                log.error("ListRMapper getList ERROR:", e);
                log.error("Data  key:" + key);
                return null;
            }
        }
    }

    /**
     * 获取分页结果中的一个集合
     * 根据key和hashkey获取一个值，并转化为castToClass所对应的类型
     *
     * @param redisTemplate
     * @param key
     * @param castToClass
     * @param <T>
     * @return
     */
    public static <T> PageInfo<T> getPage(RedisTemplate<String, Object> redisTemplate, String key, Integer pageIndex, Integer pageSize, Class<T> castToClass) {
        if (key == null) {
            return null;
        } else {
            try {
                List<T> resultList = new LinkedList<>();
                PageInfo<T> pageInfo = new PageInfo<>(resultList);
                long start = (pageIndex - 1) * pageSize;
                long end = pageIndex * pageSize - 1;
                List<Object> range = redisTemplate.opsForList().range(key, start, end);
                Long totalRecords = redisTemplate.opsForList().size(key);
                pageInfo.setTotal(totalRecords);
                int pages = (int) (totalRecords / pageSize);
                pageInfo.setPages(pages);
                if (range.isEmpty()) {
                    return null;
                } else {
                    for (Object obj :
                            range) {
                        T targetObj = (T) obj;
                        resultList.add(targetObj);
                    }
                    return pageInfo;
                }
            } catch (Exception e) {
                log.error("ListRMapper getList ERROR:", e);
                log.error("Data  key:" + key);
                return null;
            }
        }
    }

    /**
     * 添加一个对象List
     *
     * @param redisTemplate
     * @param key
     * @param list
     * @return
     */
    public static Boolean putList(RedisTemplate<String, Object> redisTemplate, String key, List list) {
        if (list == null || list.isEmpty()) {
            return false;
        } else {
            Long totalNumber = redisTemplate.opsForList().leftPushAll(key, list);
            if (totalNumber.equals(list.size())) {
                return true;
            } else {
                return false;
            }
        }
    }
    
    /**
     * 添加一个对象List的一条记录
     * @param redisTemplate
     * @param key
     * @param record
     * @return
     */
    public static Boolean putOneRecord(RedisTemplate<String, Object> redisTemplate, String key, Object record) {
        if (record == null) {
            return false;
        } else {
            Long totalNumber = redisTemplate.opsForList().leftPush(key, record);
            if (totalNumber.equals(1)) {
                return true;
            } else {
                return false;
            }
        }
    }


    /**
     * 删除key对应的缓存
     *
     * @param redisTemplate
     * @param key
     * @return
     */
    public static Boolean delRedis(RedisTemplate<String, Object> redisTemplate, String key) {
        Boolean result = false;
        if (StringUtils.isBlank(key) == false) {
            try {
                redisTemplate.delete(key);
                result = true;
            } catch (Exception e) {
                log.error("R_HashRedisMapper delRedis ERROR:", e);
                log.error("Data:" + key);
            }
        }
        return result;
    }

    /**
     * 为redis中的某个key对应的缓存设置过期时间
     *
     * @param redisTemplate
     * @param key
     * @param timeout       过期时间数值
     * @param timeunit      过期时间单位
     * @return
     */
    public static Boolean setRedisTimeout(RedisTemplate<String, Object> redisTemplate, String key, long timeout, TimeUnit timeunit) {
        Boolean result = false;
        if (key != null) {
            try {
                if (timeout == 0) {
                    redisTemplate.delete(key);
                } else {
                    redisTemplate.expire(key, timeout, timeunit);
                }
                result = true;
            } catch (Exception e) {
                log.error("R_ValueRedisMapper setRedisTimeout ERROR:", e);
                log.error("Data:" + key);
            }
        }
        return result;
    }

    /**
     * 为redis中的某个key对应的缓存设置过期时间
     *
     * @param redisTemplate
     * @param key
     * @return
     */
    public static Boolean setRedisTimeout(RedisTemplate<String, Object> redisTemplate, String key, RedisTtlConfig redisTtlConfig) {
        Boolean result = false;
        if (key != null) {
            try {
                Long time = redisTtlConfig.getTime();
                TimeUnit timeUnit = redisTtlConfig.getTimeUnit();
                if (time == 0) {
                    redisTemplate.delete(key);
                } else {
                    redisTemplate.expire(key, time, timeUnit);
                }
                result = true;
            } catch (Exception e) {
                log.error("R_ValueRedisMapper setRedisTimeout ERROR:", e);
                log.error("Data:" + key);
            }
        }
        return result;
    }
}
